<?php

namespace app\Http\Controllers;

use App\Http\Controllers\Controller;
use Encore\Admin\Form\Tab;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Auth;

class LaravelController extends Controller
{
    // 首页
    public function index(Request $request)
    {
        $data = $this->data($request);
        return view('/index', $data);
    }

    // 分类页
    public function cat(Request $request, $id_or_slug)
    {
        $data = $this->data($request, $id_or_slug);
        return view('/cat', $data);
    }

    // 标签页
    public function tag(Request $request, $id_or_slug)
    {
        $data = $this->data($request, $id_or_slug);
        return view('/tag', $data);
    }

    // 搜索页
    public function search(Request $request, $keywords)
    {
        $data = $this->data($request, $keywords);
        return view('/search', $data);
    }

    // 文章页
    public function article(Request $request, $id_or_slug)
    {
        $data = $this->data($request, $id_or_slug);
        return view('/article', $data);
    }

    // 获取数据
    private function data(Request $request, $param = null)
    {
        // 获取方法
        $action = substr(strrchr($request->route()->getActionName(), '@'), 1);
        if (strlen(trim($action)) === 0) return $this->errMsg(1, '非法访问');
        $data['action'] = $action;
        $cats = DB::table('cat')->orderBy('id', 'asc')->orderBy('order', 'desc');
        $tags = DB::table('tag')->orderBy('id', 'asc')->orderBy('order', 'desc');
        $db = DB::table('article')->where('is_del', 0)->orderBy('id', 'desc');
        $items = $db->where('status', 0)->get()->all();
        // 用户信息
        $data['user'] = Auth::user();
        // 系统设置
        $setting = DB::table('setting')->where('names', 'setting')->first();
        $setting = isset($setting->values) ? json_decode($setting->values) : null;
        $setting->siteUrl = isset($setting->siteUrl) && $setting->siteUrl ? rtrim($setting->siteUrl, '/') : '';
        $data['setting'] = $setting;
        // 导航菜单
        $menus = $cats->where('status', 0)->get()->all();
        $menus = $this->levels($menus);
        $data['menus'] = $this->menus($menus);
        // 获取分类
        $cats = $cats->format('id');
        $data['cats'] = array_map(function ($item) use ($items, $cats, $data) {
            $item->link = $data['setting']->siteUrl . '/cat/' . ($item->slug ? $item->slug : $item->id) . '.html';
            $cat_ids = array_column($this->trees($cats, $item->id), 'id');
            array_unshift($cat_ids, $item->id);
            $item->count = count(array_filter($items, function ($elem) use ($cat_ids) {
                return in_array($elem->cat_id, $cat_ids);
            }));
            return $item;
        }, $cats);
        // 获取标签
        $tags = $tags->format('id');
        $data['tags'] = array_map(function ($item) use ($items, $data) {
            $item->link = $data['setting']->siteUrl . '/tag/' . ($item->slug ? $item->slug : $item->id) . '.html';
            $item->count = count(array_filter($items, function ($elem) use ($item) {
                return in_array($item->id, (array)json_decode($elem->tags));
            }));
            return $item;
        }, $tags);
        // 首页
        $data['crumbs'][] = ['name' => '首页', 'link' => $data['setting']->siteUrl . '/'];
        if ($action === 'index') {
            // 面包屑导航
            $data['crumbs'][] = ['name' => $data['setting']->siteName ?? '', 'link' => 'javascript:;'];
        }
        // 分类页
        $data['cat'] = false;
        if ($action === 'cat') {
            if ((int)$param) {
                $cat = array_filter($cats, function ($item) use ($param) {
                    return $item->id === (int)$param;
                });
            } else {
                $cat = array_filter($cats, function ($item) use ($param) {
                    return $item->slug === $param;
                });
            }
            if (!$cat) return $this->errMsg(1, '数据错误');
            $data['cat'] = reset($cat);
            // 重写seo
            $data['setting']->title = $data['cat']->seo_title ?? $data['cat']->name;
            $data['setting']->description = $data['cat']->seo_des ?? '';
            // 面包屑导航
            $parents = $this->parents($data['cats'], $data['cat']->id);
            $data['crumbs'] = array_reduce(array_reverse($parents), function ($res, $next) use ($data) {
                $res[] = ['name' => $next->name, 'link' => $data['setting']->siteUrl . '/cat/' . ($next->slug ? $next->slug : $next->id) . '.html'];
                return $res;
            }, $data['crumbs']);
            // 更改查询
            $cat_ids = array_column(array_filter($cats, function ($item) use ($data) {
                return $item->pid === $data['cat']->id;
            }), 'id');
            array_unshift($cat_ids, $data['cat']->id);
            $db = $db->whereIn('cat_id', $cat_ids);
            // 更改图片分页
            if (isset($data['setting']->grid) && $data['cat']->id === (int)$data['setting']->grid) {
                $data['pageSize'] = $request->limit ?? 20;
                // 查询缩略图
                $db = $db->where('thumb', 'like', '%/storage/%');
            }
        }
        // 标签页
        $data['tag'] = false;
        if ($action === 'tag') {
            if ((int)($param)) {
                $tag = array_filter($tags, function ($item) use ($param) {
                    return $item->id === (int)$param;
                });
            } else {
                $tag = array_filter($tags, function ($item) use ($param) {
                    return $item->slug === $param;
                });
            }
            if (!$tag) return $this->errMsg(1, '数据错误');
            $data['tag'] = reset($tag);
            // 重写seo
            $data['setting']->title = $data['tag']->seo_title ?? $data['tag']->name;
            $data['setting']->description = $data['tag']->seo_des ?? '';
            // 面包屑导航
            $data['crumbs'][] = ['name' => $data['tag']->name, 'link' => $data['setting']->siteUrl . '/tag/' . ($data['tag']->slug ? $data['tag']->slug : $data['tag']->id) . '.html'];
            // 更改查询
            $db = $db->whereJsonContains('tags', $data['tag']->id);
        }
        // 搜索页
        if ($action === 'search') {
            // 重写seo
            $data['setting']->title = '搜索结果';
            $data['setting']->description = $param . '的搜索结果';
            // 面包屑导航
            $data['crumbs'][] = ['name' => '搜索结果', 'link' => $data['setting']->siteUrl . '/search/' . $param];
            // 更改查询
            $db = $db->where('title', 'like', "%{$param}%");
        }
        // 文章页
        if ($action === 'article') {
            if ((int)$param) {
                $article = array_filter($items, function ($item) use ($param) {
                    return $item->id === (int)$param;
                });
            } else {
                $article = array_filter($items, function ($item) use ($param) {
                    return $item->slug === $param;
                });
            }
            if (!$article) return $this->errMsg(1, '数据错误');
            $data['article'] = reset($article);
            // 重写seo
            $data['setting']->title = $data['article']->seo_title ?? $data['article']->title;
            $data['setting']->description = $data['article']->seo_des ?? ($data['article']->excerpt ?? mb_strimwidth($data['article']->content, 0, 140, ' ...', 'utf-8'));
            // 面包屑导航
            $data['cat'] = null;
            if ($data['article']->cat_id) {
                $data['cat'] = $data['cats'][$data['article']->cat_id];
                $parents = $this->parents($data['cats'], $data['cat']->id);
                $data['crumbs'] = array_reduce(array_reverse($parents), function ($res, $next) use ($data) {
                    $res[] = ['name' => $next->name, 'link' => $data['setting']->siteUrl . '/cat/' . ($next->slug ? $next->slug : $next->id) . '.html'];
                    return $res;
                }, $data['crumbs']);
            }
            $data['crumbs'][] = ['name' => '文章内容', 'link' => $data['setting']->siteUrl . '/article/' . ($data['article']->slug ? $data['article']->slug : $data['article']->id) . '.html'];
            // 相关文章
            $related = [];
            // 标签相关
            if ($data['article']->tags) {
                $tag_ids = array_map('trim', (array)json_decode($data['article']->tags));
                foreach ($tag_ids as $tag_id) {
                    $related = array_reduce($items, function ($res, $next) use ($tag_id) {
                        if (in_array($tag_id, (array)json_decode($next->tags)) && $next->thumb) {
                            $res[$next->id] = $next;
                        }
                        return $res;
                    }, $related);
                }
            }
            // 排除当前文章
            if (isset($related[$data['article']->id])) unset($related[$data['article']->id]);
            // 数量不足分类相关
            if (count($related) < ($data['setting']->related ?? 4)) {
                $related = array_reduce($items, function ($res, $next) use ($data) {
                    if ($next->cat_id === $data['article']->cat_id && $next->thumb) {
                        $res[$next->id] = $next;
                    }
                    return $res;
                }, $related);
                // 排除当前文章
                if (isset($related[$data['article']->id])) unset($related[$data['article']->id]);
            }
            // 截取数量相关文章
            $related = array_slice($related, 0, $data['setting']->related ?? 4);
            $data['related'] = $this->items($cats, $tags, $related, $data);
            // 点击数更新
            $db->where('id', $data['article']->id)->increment('views');
            // 更改查询
            $db = $db->where('id', $data['article']->id);
            $data['items'] = $this->items($cats, $tags, $db->get()->all(), $data);
            // 文章页评论
            $db = DB::table('comment')->where('post_id', $data['article']->id)->where('status', 0)->orderBy('id', 'desc');
        }
        // 热门文章
        $hots = $items;
        // if (isset($data['cats']) && isset($data['cat']->id)) {
        //     $cat_ids = array_column($this->trees($data['cats'], $data['cat']->id), 'id');
        //     array_unshift($cat_ids, $data['cat']->id);
        //     $hots = array_filter($items, function ($item) use ($cat_ids) {
        //         return in_array($item->cat_id, $cat_ids);
        //     });
        // }
        array_multisort(array_column($hots, 'views'), SORT_DESC, $hots);
        $hots = array_slice($hots, 0, $data['setting']->hots ?? 5);
        $data['hots'] = array_map(function ($item) use ($data) {
            $item->link = $data['setting']->siteUrl . '/article/' . ($item->slug ? $item->slug : $item->id) . '.html';
            return $item;
        }, $hots);
        // 分页
        $data['curPage'] = $request->page ?? 1;
        $data['pageSize'] = $data['pageSize'] ?? ($request->limit ?? 10);
        $db = $db->paginate($data['pageSize']);
        $data['total'] = $db->total();
        if (isset($data['items'])) {
            $comments = $this->levels($db->items());
            $comments = $this->comments($comments, $data);
            $data['comments'] = $comments;
        } else {
            $data['items'] = $this->items($cats, $tags, $db->items(), $data);
        }
        return $data;
    }

    // 项目数据
    private function items($cats, $tags, $items, $data)
    {
        return array_map(function ($item) use ($cats, $tags, $data) {
            $item->thumb = $item->thumb ? $item->thumb : (preg_match_all('#["\'](/storage/.+?\.[^"\']*)["\']#i', str_replace('\\', '', json_encode($item->content)), $matches) ? $matches[1][0] : '');
            $item->excerpt = mb_strimwidth(strip_tags($item->excerpt ? $item->excerpt : $item->content), 0, 150, ' ...', 'utf-8');
            $item->link = $data['setting']->siteUrl . '/article/' . ($item->slug ? $item->slug : $item->id) . '.html';
            $item->catName = $item->cat_id && isset($cats[$item->cat_id]) ? $cats[$item->cat_id]->name : '';
            $item->catLink = $item->cat_id && isset($cats[$item->cat_id]) ? ($data['setting']->siteUrl . '/cat/' . ($cats[$item->cat_id]->slug ? $cats[$item->cat_id]->slug : $cats[$item->cat_id]->id) . '.html') : '';
            $item->tags = $item->tags ? array_reduce(array_map('trim', json_decode($item->tags)), function ($res, $next) use ($tags, $data) {
                $res[] = ['name' => $tags[$next]->name, 'link' => $data['setting']->siteUrl . '/tag/' . ($tags[$next]->slug ? $tags[$next]->slug : $tags[$next]->id) . '.html'];
                return $res;
            }, []) : '';
            return $item;
        }, $items);
    }

    // 无限级菜单
    private function menus($items)
    {
        $res = '';
        foreach ($items as $k => $item) {
            $res .= $this->children($item, $k);
        }
        return $res;
    }

    // 递归子数据
    private function children($item, $k = 0, $indent = 0)
    {
        $res = '';
        if ($item->children) {
            $res .= sprintf('<li class="layui-nav-item%s">', $k === 0 ? '' : '');
            $res .= sprintf('<a href="javascript:;" title="%s">%s</a>', strip_tags($item->name), $item->name);
            $res .= '<dl class="layui-nav-child">';
            foreach ($item->children as $k => $item) {
                if ($item->children) {
                    $res .= $this->children($item, $k, $indent + 1);
                } else {
                    $res .= sprintf('<dd><a href="/cat/%s.html" title="%s">%s</a></dd>', $item->slug ? $item->slug : $item->id, strip_tags($item->name), $item->name);
                }
            }
            $res .= '</dl>';
            $res .= "</li>\n";
        } else {
            $res .= sprintf('<li class="layui-nav-item%s"><a href="/cat/%s.html" title="%s">%s</a></li>', $k === 0 ? ' lay-unselect' : '', $item->slug ? $item->slug : $item->id, strip_tags($item->name), $item->name);
        }
        return $res;
    }

    // 无限级评论
    private function comments($items, $data)
    {
        $res = '';
        foreach ($items as $item) {
            $res .= $this->childComments($item, $data);
        }
        return $res;
    }

    // 递归子数据
    private function childComments($item, $data)
    {
        $res = '';
        if ($item->children) {
            $commentData = $this->commentData($item, $item->level, $data);
            $res .= $commentData['head'];
            foreach ($item->children as $item) {
                if ($item->children) {
                    $res .= $this->childComments($item, $data);
                } else {
                    $childData = $this->commentData($item, $item->level, $data);
                    $res .= $childData['head'] . $childData['foot'];
                }
            }
            $res .= $commentData['foot'] . "\n";
        } else {
            $commentData = $this->commentData($item, $item->level, $data);
            $res .= $commentData['head'] . $commentData['foot'];
        }
        return $res;
    }

    // 限制层级评论嵌套数据
    private function commentData($item, $level, $data)
    {
        $head = '<div class="layui-row" style="margin-bottom: 15px;">
        <div class="layui-col-md12">
            <div class="layui-panel" style="padding: 10px 15px 0 15px;">
                <div class="layui-row layui-col-space15">
                    <div class="layui-col-sm1 layui-col-xs2">
                        <img src="' . ($data['user']->avatar ?? ($data['setting']->avatar ?? '')) . '" alt="avatar" style="width: 100%;padding-top: 5px;">
                    </div>
                    <div class="layui-col-sm11 layui-col-xs10">
                        <div class="layui-row">
                            <div class="layui-col-sm12">
                                <strong>' . (isset($item->name) && $item->name ? strip_tags($item->name) : '游客') . '</strong> <cite>' . ($level ? '回复' : '说道') . '：</cite>
                            </div>
                        </div>
                        <div class="layui-row">
                            <div class="layui-col-sm12" style="margin-bottom: 10px">' . strip_tags($item->comment) . '</div>
                        </div>
                        ' . ($level < ($data['setting']->commentsLevel ?? 5) ? '<div class="layui-row">
                            <div class="layui-col-sm12" style="text-align: right;margin-bottom: 15px;"><a href="javascript:;" title="留言" data-id=' . $item->id . ' data-level=' . $level . ' class="layui-btn layui-btn-sm layui-btn-primary btn-replay"><i class="layui-icon layui-icon-at"></i> 回复</a></div>
                        </div>' : '') . '
                    </div>
                </div>';
        $foot = '</div>
        </div>
    </div>';
        return compact('head', 'foot');
    }

    public function test() {
        $db = DB::table('boke');
        $res = $db->where('id', 17)->update(['title' => 'ID 17 记录修改标题']);
        $db = $db->select(['id', 'title', 'num']);
        dump($db->get()->all());
    }
}
